package com.zt.questionnaire.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * Utility methods for simple pattern matching, in particular for
 * Spring's typical "xxx*", "*xxx" and "*xxx*" pattern styles.
 *
 * @author Juergen Hoeller
 * @since 2.0
 */
public abstract class PatternUtils {

    private static Logger log = LoggerFactory.getLogger(PatternUtils.class);

    /**
     * 字符串全部是字母拼音
     **/
    public static Pattern spell_all = Pattern.compile("^[a-zA-Z]+$");

    /**
     * 字符串全部是汉字，+表示最少一个，最多不限制
     **/
    public static Pattern chinese_all = Pattern.compile("[\u4e00-\u9fa5]+");

    /**
     * 字符串是否全部是数字
     **/
    public static Pattern number_all = Pattern.compile("[0-9]{1,20}");

    /**
     * 只能输入字母、数字、“.”、“@”、“_”
     **/
    public static Pattern accountName = Pattern.compile("([a-zA-Z0-9]|[.@_]){6,30}");

    /**
     * 昵称，只能输入汉子、字母、数字、“.”、“@”、“_”
     **/
    public static Pattern nickName = Pattern.compile("([\u4e00-\u9fa5]|[a-zA-Z0-9]|[.@_]){2,8}");

    /**
     * 密码，只能输入6到19位字母、数字
     **/
    public static Pattern pwd = Pattern.compile("([a-zA-Z0-9]){6,19}");

    /**
     * 新的正则密码验证,6-19位必须包含数字和字符
     */
    public static Pattern newPwd = Pattern.compile("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,19}$");

    /**
     * 不能包含特殊字符，且不能以数字开头
     **/
    public static Pattern namer = Pattern.compile("^[a-zA-Z\\u4e00-\\u9fa5][a-zA-Z_0-9\\u4e00-\\u9fa5]{1,}");


    /**
     * 手机号码验证
     **/
    public static Pattern phone = Pattern.compile("^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[0-9]|)\\d{8}$");

    /**
     * 邮箱地址正则表达式
     */
    public static Pattern emailer = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");

    /**
     * 身份证 15，18位
     */
    public static Pattern idCard = Pattern.compile("(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)");

    /**
     * sql语句的限制字符。客户端输入的字符串里面不能包含sql语句的字符，否则可能会组装sql语句修改数据库数据
     **/
    public static String[] SQL_LIMITS = {
        "'",
        "and",
        "exec",
        "insert",
        "select",
        "delete",
        "update",
        "count",
        "*",
        "%",
        "chr",
        "mid",
        "master",
        "truncate",
        "char",
        "declare",
        "; ",
        ";",
        "or",
        "-",
        "+",
        ","
    };

    public static void main(String[] args) {
        System.out.println(isIdCard("413026199906181519X"));
        System.out.println(isPhone("17821259740"));
        System.out.println(isChinese(""));
        System.out.println(isPwd("123456"));
        System.out.println(isPhone("15012062058"));
        System.out.println(isPhone("19216021191"));
        System.out.println(isContainChinese("冰糖+饴糖或木糖醇"));
    }

    /**
     * 是否全部是拼音字母
     *
     * @param str
     * @return
     */
    public static boolean isSpell(String str) {
        if (str == null || "".equals(str)) {
            return false;
        }
        return spell_all.matcher(str).matches();
    }

    /**
     * 是否未身份证号
     *
     * @param str
     * @return
     */
    public static boolean isIdCard(String str) {
        if (str == null || "".equals(str)) {
            return false;
        }
        return idCard.matcher(str).matches();
    }

    /**
     * 是否全部是汉字
     *
     * @param str
     * @return
     */
    public static boolean isChinese(String str) {
        if (str == null || "".equals(str)) {
            return false;
        }
        return chinese_all.matcher(str).matches();
    }

    /**
     * 是否包含汉字
     *
     * @param str
     * @return
     */
    public static boolean isContainChinese(String str) {
        if (str == null || "".equals(str)) {
            return false;
        }
        return chinese_all.matcher(str).find();
    }

    /**
     * 是否全部是数字
     *
     * @param mobiles
     * @return
     */
    public static boolean isNum(String str) {
        return number_all.matcher(str).matches();
    }

    /**
     * 只能输入字母、数字、“.”、“@”、“_”，可以用来验证账号
     *
     * @param mobiles
     * @return
     */
    public static boolean isAccount(String str) {
        return accountName.matcher(str).matches();
    }

    /**
     * 只能输入字母、数字、“.”、“@”、“_”，且不能全部是数字
     *
     * @param str
     * @return
     */
    public static boolean isAccountNotAllNum(String str) {
        if (isNum(str)) {
            return false;
        }
        return accountName.matcher(str).matches();
    }

    /**
     * 只能输入6到19位字母、数字，可以用于密码
     *
     * @param str
     * @return
     */
    public static boolean isPwd(String str) {
        return pwd.matcher(str).matches();
    }

    public static boolean isNewPwd(String str) {
        return newPwd.matcher(str).matches();
    }

    /**
     * 只能输入汉子、字母、数字、“.”、“@”、“_”，可以用来验证昵称
     *
     * @param str
     * @return
     */
    public static boolean isName(String str) {
        return nickName.matcher(str).matches();
    }

    /**
     * 是否是手机号码
     *
     * @param str
     * @return
     */
    public static boolean isPhone(String str) {
        boolean is = phone.matcher(str).matches();
        if (!is) {
            log.error("手机号码格式错误,phone={}", str);
        }
        return is;
    }

    /**
     * 是否是邮箱
     *
     * @param str
     * @return
     */
    public static boolean isEmail(String str) {
        return emailer.matcher(str).matches();
    }


    /**
     * Match a String against the given pattern, supporting the following simple
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
     * arbitrary number of pattern parts), as well as direct equality.
     *
     * @param pattern the pattern to match against
     * @param str     the String to match
     * @return whether the String matches the given pattern
     */
    public static boolean simpleMatch(String pattern, String str) {
        if (pattern == null || str == null) {
            return false;
        }
        int firstIndex = pattern.indexOf('*');
        if (firstIndex == -1) {
            return pattern.equals(str);
        }
        if (firstIndex == 0) {
            if (pattern.length() == 1) {
                return true;
            }
            int nextIndex = pattern.indexOf('*', firstIndex + 1);
            if (nextIndex == -1) {
                return str.endsWith(pattern.substring(1));
            }
            String part = pattern.substring(1, nextIndex);
            int partIndex = str.indexOf(part);
            while (partIndex != -1) {
                if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()))) {
                    return true;
                }
                partIndex = str.indexOf(part, partIndex + 1);
            }
            return false;
        }
        return (str.length() >= firstIndex &&
            pattern.substring(0, firstIndex).equals(str.substring(0, firstIndex)) &&
            simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex)));
    }

    /**
     * Match a String against the given patterns, supporting the following simple
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
     * arbitrary number of pattern parts), as well as direct equality.
     *
     * @param patterns the patterns to match against
     * @param str      the String to match
     * @return whether the String matches any of the given patterns
     */
    public static boolean simpleMatch(String[] patterns, String str) {
        if (patterns != null) {
            for (int i = 0; i < patterns.length; i++) {
                if (simpleMatch(patterns[i], str)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判定是否是内网IP
     *
     * @param ip
     * @return
     */
    public static boolean isInner(String ip) {
        String reg = "(10|172|192)\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})\\.([0-1][0-9]{0,2}|[2][0-5]{0,2}|[3-9][0-9]{0,1})";//正则表达式=。 =、懒得做文字处理了、
        Pattern p = Pattern.compile(reg);
        Matcher matcher = p.matcher(ip);
        return matcher.find();
    }

}
